package controller

import (
	"errors"

	"fairysunny.com/gin-example/model"
	"fairysunny.com/gin-example/util"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

func CreatePost(c *gin.Context) {
	var form struct {
		Title   string `json:"title" binding:"min=1,max=50"`
		Content string `json:"content" binding:"min=1,max=500"`
	}
	if err := c.ShouldBindJSON(&form); err != nil {
		util.ResParamErr(c, err.Error())
		return
	}
	session := sessions.Default(c)
	id := session.Get("user-id").(int)
	post := model.Post{
		UserID:  id,
		Title:   form.Title,
		Content: form.Content,
	}
	result := model.DB.Create(&post)
	if err := result.Error; err != nil {
		util.ResSysErr(c, err.Error())
		return
	}
	util.ResOK(c, gin.H{"id": post.ID})
}

func DeletePost(c *gin.Context) {
	form := util.IDUriForm{}
	if err := c.ShouldBindUri(&form); err != nil {
		util.ResParamErr(c, err.Error())
		return
	}
	session := sessions.Default(c)
	id := session.Get("user-id").(int)
	result := model.DB.Where("user_id = ?", id).Delete(&model.Post{ID: form.ID})
	if err := result.Error; err != nil {
		util.ResSysErr(c, err.Error())
		return
	}
	if result.RowsAffected == 0 {
		util.ResErr(c, "ID不存在或作者非当前用户")
		return
	}
	util.ResOK(c, gin.H{})
}

func UpdatePost(c *gin.Context) {
	var form struct {
		ID      int    `json:"id" binding:"min=1"`
		Title   string `json:"title" binding:"min=1,max=50"`
		Content string `json:"content" binding:"min=1,max=500"`
	}
	if err := c.ShouldBindJSON(&form); err != nil {
		util.ResParamErr(c, err.Error())
		return
	}
	session := sessions.Default(c)
	id := session.Get("user-id").(int)
	result := model.DB.Model(&model.Post{ID: form.ID}).Where("user_id = ?", id).Updates(map[string]interface{}{
		"Title":   form.Title,
		"Content": form.Content,
	})
	if err := result.Error; err != nil {
		util.ResSysErr(c, err.Error())
		return
	}
	if result.RowsAffected == 0 {
		util.ResErr(c, "ID不存在或作者非当前用户")
		return
	}
	util.ResOK(c, gin.H{})
}

func GetPost(c *gin.Context) {
	form := util.IDUriForm{}
	if err := c.ShouldBindUri(&form); err != nil {
		util.ResParamErr(c, err.Error())
		return
	}
	post := model.Post{ID: form.ID}
	result := model.DB.Joins("User").Take(&post)
	if err := result.Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			util.ResErr(c, "ID不存在")
		} else {
			util.ResSysErr(c, err.Error())
		}
		return
	}
	util.ResOK(c, gin.H{"post": post})
}

func GetAllPosts(c *gin.Context) {
	form := util.PagerForm{}
	if err := c.ShouldBindQuery(&form); err != nil {
		util.ResParamErr(c, err.Error())
		return
	}
	var total int64
	var posts []model.Post
	result := model.DB.Model(&model.Post{}).Count(&total).Limit(form.Limit).Offset((form.Page - 1) * form.Limit).Joins("User").Find(&posts)
	if err := result.Error; err != nil {
		util.ResSysErr(c, err.Error())
		return
	}
	util.ResOK(c, gin.H{"total": total, "posts": posts})
}
